home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 4_0 / FPTOSTR_ / GVWUTILS.C1 < prev    next >
Text File  |  1989-05-22  |  8KB  |  289 lines

  1. /************************************************************************
  2.  
  3.     GVWUtils881.c
  4.     
  5.     ======    USE THIS SOURCE ONLY IF THE MC68881/2 MATH    ====
  6.     ======    CO-Processor  IS BEING USED!                ====
  7.     
  8.     This is a collection of utility routines, some gleaned from
  9.     Compuserve, and others from various other sources. 
  10.  
  11.      Copyright ⌐ 1988,1989 George V. Woodrow III. All Rights Reserved
  12.     
  13.     Author:                George V. Woodrow III
  14.     Created:            September 12, 1988
  15.     Last Revision:        8:52:21 PM  5/22/89
  16.     
  17.     Revision History:
  18.      9:22:12 AM   5/22/89    Added code to allow correct operation with
  19.                              FPU.
  20.      8:52:21 PM   5/22/89    removed non-standard #defines
  21.  ***********************************************************************/
  22.  
  23.  #include    "MacTypes.h"
  24.  #include    <math.h>        /*    has the typedef for Extended80. etc */
  25.  
  26.  /***********************************************************************
  27.      CONTENTS:
  28.          1.    Boolean        str2fp(buf,x)                converts string to float
  29.          2.    StringPtr    fp2str(x,buf,fmt,ndec)        converts fp to string
  30.   ************************************************************************/
  31.   
  32.   /**********************************************************************
  33.    *    Code from LSC MathHybrid to handle conversion from the SANE double
  34.    *    (80 bits) to the 881 double (96 bits), and back.  This is necessary
  35.    *    because the Dec2Str() routine expects a SANE double.
  36.    ***********************************************************************/
  37.    
  38. /* the 80-bit extended "_x80" is used as the destination to convert the 
  39. arguments to SANE doubles. */
  40. static Extended80 _x80;
  41.  
  42.   /* routines for conversion between 80- and 96-bit formats */
  43.  
  44. void x80tox96(x80, x96)
  45. register Extended80 *x80;
  46. register Extended96 *x96;
  47. {
  48.     (*x96).exponent = (*x80).exponent;
  49.     (*x96).reserved = 0;
  50.     (*x96).mantissa = (*x80).mantissa;
  51. }
  52.  
  53. void x96tox80(x96, x80)
  54. register Extended96 *x96;
  55. register Extended80 *x80;
  56.  
  57. {
  58.     (*x80).exponent = (*x96).exponent;
  59.     (*x80).mantissa = (*x96).mantissa;
  60. }
  61.  
  62. #define _x80tox96(x80, x96) x80tox96(&x80, &x96)
  63. #define _x96tox80(x96, x80) x96tox80(&x96, &x80)
  64.  
  65. #define _to80(x)  _x96tox80(x, _x80);
  66. #define _to96(x)  _x80tox96(_x80, x);
  67.  
  68.  
  69.  
  70.  /***********************************************************************
  71.  
  72.      str2fp(buf,x)
  73.      
  74.      converts string in buf to double, x
  75.      Uses SANE, but does not need sane.h, the structures required are defined
  76.      
  77.      fp2str(x,buf,fmt,ndec)
  78.      
  79.      converts double x into string put in buf
  80.      fmt    = 0        floating point style x.xx e yy
  81.          = 1        fixed point xxx.xx
  82.      
  83.      ndec    float:    number of significant digits 
  84.              fixed:    number of digits to right of decimal
  85.      
  86.      Unknown download from Compuserve. [75236,3146]
  87.      Some corrections and clarifications made.
  88.      12/6/88        fp2str modified to allow extra arguments
  89.      
  90.  ************************************************************************/
  91.  
  92. /*
  93.  *    The first structure represents formatting information.
  94.  *    Apple Numerics Manual,2nd edition, p 26. q.v. for more info.
  95.  *
  96.  *    The next structure represents floats: the value v is
  97.  *    
  98.  *    v  = (-1) ^sgn  *  sig  * 10 ^ exp
  99.  *    
  100.  *    Apple Numerics Manual 2nd edition, p 27 q.v. for more info    
  101.  */
  102.  
  103.     
  104. struct decform {
  105.     char            style;        /*    0 = floating point style x.xx e ▒yy
  106.                                     1 = fixed style    xx.xxx                    */
  107.     short           digits;        /*    float:    # of sig digits
  108.                                     fixed:    # of digits to right of decimal    */
  109. };
  110.  
  111. struct decimal {
  112.     char            sgn;        /*    sign 0 = pos, 1 = neg            */
  113.     short           exp;        /*    exponent    16 bit integer        */
  114.     unsigned char   sig[21];    /*    significand as decimal integer    */
  115. };
  116.  
  117.  
  118.  
  119. pascal void Dec2Str(), Str2Dec();    /* SANE procedures    */
  120.  
  121. /**        PROCEDURE Dec2Str(f: DecForm; d: Decimal; var s: DecStr);
  122.             is described on p 31 of the Apple Numerics Manual. You set up the
  123.             DecForm f and stuff the number into Decimal d, and the function will
  124.             stick the string into the string s.  You pass its address.
  125.     
  126.         PROCEDURE Str2Dec(s: DecStr; var Index: integer; var d: Decimal;
  127.             var ValidPrefix: Boolean );    
  128.             is described on p 30 of the Apple Numerics Manual.  Index should
  129.             point to thestarting position in the string; on output, it is one
  130.             greater than the position of the last character in the numeric
  131.             substring just parsed.  If no numeric substring is recognized, it
  132.             retains the same value.  Boolean is true if all went well.                    **/
  133.  
  134. /**************************************************
  135.  
  136.     fp2str(x, buf,fmt,ndec)
  137.     send it x, a floating point number, fmt, the type of represenatation,
  138.     ndec, the number of digits, and buf, a string pointer.
  139.     the function returns a pointer to the converted string
  140.     which may be buf, or buf[1]
  141.  
  142.     Sample use:
  143.                     double            x;
  144.                     Str255             buf1;
  145.                     StringPtr        buf2;
  146.                     StringPtr        fp2str();
  147.  
  148.                     TextFont(4);
  149.                     x = 125823.452258985412026;                 
  150.                     MoveTo( 10,20);
  151.                     DrawString(fp2str(x, buf1,0,5));
  152.             
  153.             The following is an example of how to right justify a number.
  154.             In practice, the field width would be a variable, and you would
  155.             need to check to make sure that buf[0] is <= the field width.
  156.             Note that this procedure requires monospaced fonts.
  157.             
  158.          
  159.                     x = 78.357*9;
  160.                     
  161.                     MoveTo( 150,20);
  162.                     DrawString(fp2str(x,buf1,0,5));
  163.                     for (i = 0 ;i < 15 ; i++)
  164.                     {
  165.                     buf2 = fp2str(x,buf1,1,3);
  166.                     MoveTo( 150,12*(i+6));
  167.                     for (j = 1 ; j < 10 - buf2[0] ; DrawChar(32) , j++ )
  168.                     ;
  169.                     DrawString(buf2);
  170.                     x -= 78.357;
  171.                     };
  172.                     
  173.               end of formatting demo  
  174.             
  175.  
  176. **********************************************************************/
  177. StringPtr    fp2str(x, buf, fmt, ndec)
  178. double        x;        /*    actually an Extended96    */
  179. StringPtr    buf;
  180. char        fmt;
  181. short        ndec;
  182. {
  183.     struct decform f;
  184.     struct decimal d;
  185.     int i;
  186.  
  187.         /*  convert float --> decimal record  */
  188.         
  189.     /*    convert to sane double     */
  190.     _to80(x);    /*    _x80 has result    */
  191.  
  192.     f.style = fmt;        
  193.     f.digits = ndec;        
  194.     asm {
  195.         pea     f
  196.         pea     _x80
  197.         pea     d
  198.         move.w  #0x000B,-(sp)
  199.         _FP68K
  200.     }    /*    end of asm    */
  201.  
  202.         /*  convert decimal record --> string  */
  203.  
  204.     if (d.sig[1] == '0')        /* is number 0 ?        */
  205.         {
  206.             f.style = 1;            /*    fixed style            */
  207.         }
  208.     else                            /*    number is not 0        */
  209.         {
  210.             for (i = d.sig[0]; i > 1 && d.sig[i] == '0'; --i, ++d.exp)
  211.                 ;
  212.             d.sig[0] = i;
  213.  
  214.                 i = -d.exp;
  215.                 if (i> ndec)
  216.                 {
  217.                 f.digits = i;
  218.                 } 
  219.         }    /*    end of if--else    */
  220.         
  221.     Dec2Str(f, &d, buf);
  222.     /*    put a leading space in front of positive numbers in fixed format */
  223.     if (x > 0 && fmt == 1)
  224.         {
  225.         for (i = buf[0] +1 ; i > 1 ; i--)
  226.             {
  227.                 buf[i] = buf[i-1];
  228.             }
  229.             buf[0]++;
  230.             buf[1] = ' ';
  231.         }
  232.     return(&buf[0]);
  233. }    /*    end of fp2str()        */
  234.  
  235.  
  236. /************************************************************************
  237.  
  238.     str2fp() - convert string to float
  239.     
  240.     returns TRUE if conversion was ok
  241.     Sample use:
  242.             x = 123.45686;
  243.             buf2 = fp2str(x,buf1,1,6);
  244.             MoveTo( 20,270);
  245.             DrawString(buf2);                    show  whole number     
  246.             buf2 = fp2str(x,buf1,1,3);
  247.             MoveTo( 120,270);
  248.             DrawString(buf2);                    show truncated number     
  249.             i = str2fp(buf2,&x);                turn string into number     
  250.             buf2 = fp2str(x,buf1,1,6);
  251.             MoveTo( 320,270);
  252.             DrawString(buf2);                    show  whole number
  253.             
  254.             the output is  123.456860   123.457     123.457000
  255.  
  256. ********************************************************************/
  257.  
  258. Boolean    str2fp(buf, x)
  259. StringPtr buf;
  260. double *x;
  261. {
  262.     short i, n, valid;
  263.     struct decimal d;
  264.  
  265.         /*  trim trailing blanks  */
  266.  
  267.     for (n = buf[0]; buf[n] == ' '; --n)
  268.         ;
  269.     buf[0] = n;
  270.  
  271.         /*  convert string --> decimal record  */
  272.  
  273.     i = 1;
  274.     Str2Dec(buf, &i, &d, &valid);
  275.     if (i <= n)
  276.         return(false);
  277.  
  278.         /*  convert decimal record --> float  */
  279.  
  280.     asm {
  281.         pea     d
  282.         move.l  _x80,-(sp)
  283.         move.w  #0x0009,-(sp)
  284.         _FP68K
  285.     }
  286.     _to96(*x);
  287.     return(true);
  288. }
  289.